package com.cn.xiaonuo.tcrfinance.xmpay.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cn.xiaonuo.common.entity.BusinessMessage;
import com.cn.xiaonuo.common.utils.*;
import com.cn.xiaonuo.common.vo.ExcelData;
import com.cn.xiaonuo.core.pojo.response.ResponseData;
import com.cn.xiaonuo.tcrfinance.tcrorder.entity.PvOrder;
import com.cn.xiaonuo.tcrfinance.tcrorder.entity.ReflectRecord;
import com.cn.xiaonuo.tcrfinance.tcrorder.entity.ReflectSummary;
import com.cn.xiaonuo.tcrfinance.tcrorder.mapper.PvOrderMapper;
import com.cn.xiaonuo.tcrfinance.tcrorder.param.ReflectRecordParam;
import com.cn.xiaonuo.tcrfinance.tcrshops.entity.PlatformEntity;
import com.cn.xiaonuo.tcrfinance.tcrshops.mapper.PlatformMapper;
import com.cn.xiaonuo.tcrfinance.tcrshops.param.PlatformParam;
import com.cn.xiaonuo.tcrfinance.xmpay.entity.BindCardApply;
import com.cn.xiaonuo.tcrfinance.xmpay.entity.Member;
import com.cn.xiaonuo.tcrfinance.xmpay.entity.MemberWithdrawal;
import com.cn.xiaonuo.tcrfinance.xmpay.mapper.BindCardApplyMapper;
import com.cn.xiaonuo.tcrfinance.xmpay.mapper.MemberMapper;
import com.cn.xiaonuo.tcrfinance.xmpay.mapper.MemberWithdrawalMapper;
import com.cn.xiaonuo.tcrfinance.xmpay.param.*;
import com.cn.xiaonuo.tcrfinance.xmpay.service.MemberService;
import com.cn.xiaonuo.tcrfinance.xmpay.utils.XmPayJwtTokenUtil;
import com.cn.xiaonuo.tcrfinance.xmpay.vo.*;
import com.cn.xiaonuo.tcrfinance.xmpay.vo.ApplyWithdrawReqVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MemberServiceImpl implements MemberService {

    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private PlatformMapper platformDao;
    @Resource
    private RestTemplate restTemplate;

    @Autowired
    private PvOrderMapper pvOrderMapper;

    @Value("${xiamenPay.platformBranchFundInquiry}")
    private String platformBranchFundInquiry;

    @Value("${xiamenPay.memberBranchFundInquiry}")
    private String memberBranchFundInquiry;

    @Value("${xiamenPay.platformSee}")
    private String platformSee;

    @Value("${xiamenPay.checkFileDownload}")
    private String checkFileDownload;

    @Value("${xiamenPay.remitUrl}")
    private String remitUrl;

    @Value("${xiamenPay.sendVerificationCode}")
    private String sendVerificationCode;

    @Value("${xiamenPay.platCompanyNo}")
    private String platCompanyNo;

    @Value("${xiamenPay.memberWithdrawal}")
    private String memberWithdrawal;

    @Autowired
    private BindCardApplyMapper bindCardApplyMapper;

    @Autowired
    private MemberWithdrawalMapper memberWithdrawalMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public BusinessMessage queryShopList(MemberParam memberParam) {
        BusinessMessage message = new BusinessMessage<>();
        PageHelper.startPage(memberParam.getPageNo(), memberParam.getPageSize());
        List<MemberVo> memberVos = memberMapper.queryShopList(memberParam);
        PageInfo<MemberVo> listPage = new PageInfo<>(memberVos);

        message.setData(listPage);
        message.setMessage("成功");
        message.setSuccess(true);
        message.setCode("200");
        return message;
    }


    @Override
    public BusinessMessage selcetInGoldemDeatail(PlatformParam params) {
        BusinessMessage message = new BusinessMessage();
        try {
            Integer pageSize = params.getPageSize();
            Integer pageNum = params.getPageNo();
            if (null == pageNum || Integer.valueOf(pageNum) <= 1) {
                pageNum = 1;
            }
            if (null == pageSize || Integer.valueOf(pageSize) <= 1) {
                pageSize = 10;
            }
            PlatformEntity platformEntity = new PlatformEntity();
            BeanUtil.copyProperties(params, platformEntity);
            PageHelper.startPage(pageNum, pageSize);
            List<Map<String, Object>> resultList = platformDao.selcetInGoldemDeatail2(platformEntity);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("sumTotal", platformDao.selcetInGoldemDeatailTotal2(platformEntity));
            if (resultList.size() >= 0) {
                PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(resultList);
                resultMap.put("pageInfo", pageInfo);
                message.setData(resultMap);
                message.setSuccess(true);
                message.setMessage(ResponseData.DEFAULT_SUCCESS_MESSAGE);
                message.setCode("200");
            } else {
                message.setMessage("无数据");
                message.setSuccess(false);
                message.setCode("-1");
            }
        } catch (Exception e) {
            message.setMessage("无数据");
            message.setSuccess(false);
            message.setCode("-1");
            e.printStackTrace();
        }
        return message;

    }

    @Override
    public BusinessMessage selcetOutGoldemDeatail(ReflectRecordParam reflectRecordParam) {
        BusinessMessage message = new BusinessMessage();
        try {
            Integer pageSize = reflectRecordParam.getPageSize();
            Integer pageNo = reflectRecordParam.getPageNo();
            if (null == pageNo || Integer.valueOf(pageNo) <= 1) {
                pageNo = 1;
            }
            if (null == pageSize || Integer.valueOf(pageSize) <= 1) {
                pageSize = 10;
            }
            ReflectRecord reflectRecord = new ReflectRecord();
            BeanUtil.copyProperties(reflectRecordParam, reflectRecord);
            if (null != reflectRecordParam.getBeginTime() && null != reflectRecordParam.getEndTime()) {
                Map<String, String> map = new HashMap<>(16);
                map = DateUtils.converTime(reflectRecordParam.getBeginTime(), reflectRecordParam.getEndTime());
                reflectRecord.setBeginTime(map.get("begin"));
                reflectRecord.setEndTime(map.get("end"));
            }
            if (null != reflectRecordParam.getDkBegin() && null != reflectRecordParam.getDkEnd()) {
                Map<String, String> map = new HashMap<>(16);
                map = DateUtils.conversionTime(reflectRecordParam.getDkBegin(), reflectRecordParam.getDkEnd());
                reflectRecord.setDkBegin(map.get("begin"));
                reflectRecord.setDkEnd(map.get("end"));
            }

            PageHelper.startPage(pageNo, pageSize);
            List<Map<String, Object>> resultList = platformDao.selcetOutGoldemDeatail2(reflectRecord);
            Map<String, Object> resultMap = new HashMap<>();
            ReflectSummary reflectSummary = platformDao.reflectCount2(reflectRecord);
            if (reflectSummary == null) {
                reflectSummary = new ReflectSummary();
            }
            resultMap.put("sumSXF", reflectSummary.getSumSXF());
            resultMap.put("sumDrawMoney", reflectSummary.getSumDrawMoney());
            resultMap.put("sumTotalAmount", reflectSummary.getSumTotalAmount());
            resultMap.put("sumTXMoney", reflectSummary.getSumTXMoney());
            if (resultList.size() >= 0) {
                PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(resultList);
                resultMap.put("pageInfo", pageInfo);
                message.setData(resultMap);
                message.setSuccess(true);
                message.setMessage(ResponseData.DEFAULT_SUCCESS_MESSAGE);
                message.setCode("200");
            } else {
                message.setMessage("无数据");
                message.setSuccess(false);
                message.setCode("-1");
            }
        } catch (Exception e) {
            message.setMessage("无数据");
            message.setSuccess(false);
            message.setCode("-1");
            e.printStackTrace();
        }
        return message;
    }

    @Override
    public BusinessMessage selectRemitDetail(ReflectRecordParam reflectRecordParam) {
        BusinessMessage message = new BusinessMessage();
        try {
            Integer pageSize = reflectRecordParam.getPageSize();
            Integer pageNo = reflectRecordParam.getPageNo();
            if (null == pageNo || Integer.valueOf(pageNo) <= 1) {
                pageNo = 1;
            }
            if (null == pageSize || Integer.valueOf(pageSize) <= 1) {
                pageSize = 10;
            }
            ReflectRecord reflectRecord = new ReflectRecord();
            BeanUtil.copyProperties(reflectRecordParam, reflectRecord);
            if (null != reflectRecordParam.getBeginTime() && null != reflectRecordParam.getEndTime()) {
                Map<String, String> map = new HashMap<>(16);
                map = DateUtils.converTime(reflectRecordParam.getBeginTime(), reflectRecordParam.getEndTime());
                reflectRecord.setBeginTime(map.get("begin"));
                reflectRecord.setEndTime(map.get("end"));
            }
            if (null != reflectRecordParam.getDkBegin() && null != reflectRecordParam.getDkEnd()) {
                Map<String, String> map = new HashMap<>(16);
                map = DateUtils.conversionTime(reflectRecordParam.getDkBegin(), reflectRecordParam.getDkEnd());
                reflectRecord.setDkBegin(map.get("begin"));
                reflectRecord.setDkEnd(map.get("end"));
            }
            PageHelper.startPage(pageNo, pageSize);
            List<Map<String, Object>> resultList = platformDao.selectRemitDetail2(reflectRecord);
            if (resultList == null || resultList.size() < 0) {
                message.setSuccess(false);
                message.setMessage("无数据");
                message.setCode("-1");
                return message;
            }
            PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(resultList);
            Map<Object, Object> resultMap = new HashMap<>();
            ReflectSummary reflectSummary = platformDao.selectRemitDetailSum2(reflectRecord);
            if (reflectSummary == null) {
                reflectSummary = new ReflectSummary();
            }
            resultMap.put("pageInfo", pageInfo);
            resultMap.put("sumMoney", reflectSummary.getSumMoney());
            resultMap.put("sumSXF", reflectSummary.getSumSXF());
            resultMap.put("sumTXMoney", reflectSummary.getSumTXMoney());
            message.setData(resultMap);
            message.setSuccess(true);
            message.setMessage(ResponseData.DEFAULT_SUCCESS_MESSAGE);
            message.setCode("200");
            return message;
        } catch (Exception e) {
            message.setSuccess(false);
            message.setMessage("无数据");
            message.setCode("-1");
            e.printStackTrace();
        }
        return message;
    }

    @Override
    public BusinessMessage platformBranchFundInquiry() {
        BusinessMessage message = new BusinessMessage();
        try {

            Member member = memberMapper.selectOne(
                    Wrappers.lambdaQuery(Member.class)
                            .eq(Member::getPlatCustNo, platCompanyNo)
                            .eq(Member::getDeleted, 0)
            );

            BranchFundInquiryParam param = new BranchFundInquiryParam();
            param.setAcctType(SubAccountType.NORMAL);
            String returnJson = XmPayJwtTokenUtil.xmPayPost(restTemplate, platformBranchFundInquiry, JSONObject.toJSONString(param),member.getIdNo());
            Map mapNormal = JSONObject.parseObject(returnJson);

            param.setAcctType(SubAccountType.TRADEFEE);
            String returnJsonFee = XmPayJwtTokenUtil.xmPayPost(restTemplate, platformBranchFundInquiry, JSONObject.toJSONString(param),member.getIdNo());
            Map mapTradefee =  JSONObject.parseObject(returnJsonFee);

            param.setAcctType(SubAccountType.WITHDRAWFEE);
            Map mapWithdrawfee = JSONObject.parseObject(XmPayJwtTokenUtil.xmPayPost(restTemplate, platformBranchFundInquiry, JSONObject.toJSONString(param),member.getIdNo()));

            param.setAcctType(SubAccountType.MARKETINGFEE);
            Map mapMarketingfee = JSONObject.parseObject(XmPayJwtTokenUtil.xmPayPost(restTemplate, platformBranchFundInquiry, JSONObject.toJSONString(param),member.getIdNo()));

            param.setAcctType(SubAccountType.TRANSFERAUTHFEE);
            Map mapTransferauthfee = JSONObject.parseObject(XmPayJwtTokenUtil.xmPayPost(restTemplate, platformBranchFundInquiry, JSONObject.toJSONString(param),member.getIdNo()));


            BigDecimal bigDecimal = new BigDecimal("0");
            BigDecimal add = bigDecimal.add(new BigDecimal((String) ((Map) mapNormal.get("data")).get("bal")))
                    .add(new BigDecimal((String) ((Map) mapTradefee.get("data")).get("bal")))
                    .add(new BigDecimal((String) ((Map) mapWithdrawfee.get("data")).get("bal")))
                    .add(new BigDecimal((String) ((Map) mapMarketingfee.get("data")).get("bal")))
                    .add(new BigDecimal((String) ((Map) mapTransferauthfee.get("data")).get("bal")));
            Map<String,Object> objectMap = Maps.newHashMap();
            objectMap.put("total",add);
            objectMap.put("mapNormal",new BigDecimal((String) ((Map) mapNormal.get("data")).get("bal")));
            objectMap.put("mapTradefee",new BigDecimal((String) ((Map) mapTradefee.get("data")).get("bal")));
            objectMap.put("mapWithdrawfee",new BigDecimal((String) ((Map) mapWithdrawfee.get("data")).get("bal")));
            objectMap.put("mapMarketingfee",new BigDecimal((String) ((Map) mapMarketingfee.get("data")).get("bal")));
            objectMap.put("mapTransferauthfee",new BigDecimal((String) ((Map) mapTransferauthfee.get("data")).get("bal")));
            message.setSuccess(true);
            message.setData(objectMap);
            return message;
        }catch (Exception e){
            e.printStackTrace();
            message.setMessage("查询失败！");
            return message;
        }
    }

    @Override
    public BusinessMessage memberBranchFundInquiry(BranchFundInquiryParam param) {
        Member member2 = memberMapper.selectOne(
                Wrappers.lambdaQuery(Member.class)
                        .eq(Member::getPlatCustNo, platCompanyNo)
                        .eq(Member::getDeleted, 0)
        );
        Member member = memberMapper.selectOne(new QueryWrapper<Member>().eq("user_id", param.getUserId()));
        param.setPlatCustNo(member.getPlatCustNo());
        param.setIdNo(member.getIdNo());
        String json = XmPayJwtTokenUtil.xmPayPost(restTemplate, memberBranchFundInquiry, JSONObject.toJSONString(param),member2.getIdNo());
        JSONObject returnJson = JSONObject.parseObject(json);
        if (!returnJson.getBoolean("success")){
            return new BusinessMessage() {{
                setCode("-1");
                setMessage("查询失败！");
                setSuccess(false);
            }};
        }
        BusinessMessage message = new BusinessMessage();
        message.setSuccess(true);
        message.setData(returnJson.get("data"));
        return message;
    }

    @Override
    public void checkCommonFileDownload(CheckFileDownloadReqVo reqVo, HttpServletResponse response) {
        CheckFileDownloadParam checkFileDownloadParam = new CheckFileDownloadParam();
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDate beginDate = LocalDate.parse(reqVo.getBeginDate(), fmt);
        LocalDate endDate = LocalDate.parse(reqVo.getEndDate(), fmt);
        checkFileDownloadParam.setBeginDate(beginDate);
        checkFileDownloadParam.setEndDate(endDate);
        Member member = memberMapper.selectOne(
                Wrappers.lambdaQuery(Member.class)
                        .eq(Member::getUserId, reqVo.getUserId())
                        .eq(Member::getDeleted, 0)
        );
        Member member2 = memberMapper.selectOne(
                Wrappers.lambdaQuery(Member.class)
                        .eq(Member::getPlatCustNo, platCompanyNo)
                        .eq(Member::getDeleted, 0)
        );
        checkFileDownloadParam.setIdNo(member.getIdNo());
        String returnJson = XmPayJwtTokenUtil.xmPayPost(restTemplate, checkFileDownload, JSONObject.toJSONString(checkFileDownloadParam),member2.getIdNo());
        JSONObject jsonObject = JSONObject.parseObject(returnJson);
        List<ExcelData> excelData = JSONObject.parseArray(jsonObject.getString("data"), ExcelData.class);

        String downloadFileName = "XMCheckFile"
                + reqVo.getBeginDate() + "--"
                + reqVo.getEndDate() + ".xls";
        try {
            ExportExcelUtils.exportExcel(response, downloadFileName, excelData);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("对账文件明细下载失败!" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public BusinessMessage updateRemitStatus(Map<String, Object> params) {
        BusinessMessage message = new BusinessMessage();
        try {
            if (params.get("verificationCode") == null){
                message.setMessage("验证码不能为空！！！");
                message.setSuccess(false);
                message.setCode("-1");
                return message;
            }

            Integer orderId = (Integer) params.get("orderId");
            if (params.get("orderId") instanceof Integer) {
                orderId = (Integer) params.get("orderId");
            }
            List<Integer> orderIds1 = Lists.newArrayList();
            orderIds1.add(orderId);
            BusinessMessage message1 = checkoutOrder(message, orderIds1);
            if (message1 != null){
                return message1;
            }
            if (params.get("orderId") instanceof String) {
                if (StringUtils.isBlank((String) params.get("orderId"))) {
                    message.setMessage("订单ID不能为空");
                    message.setSuccess(false);
                    message.setCode("-1");
                    return message;
                } else {
                    orderId = Integer.valueOf((String) params.get("orderId"));
                }
            }
            Integer loginUserId = null;
            if (params.get("loginUserId") instanceof Integer) {
                loginUserId = (Integer) params.get("loginUserId");
            }
            if (params.get("loginUserId") instanceof String) {
                if (StringUtils.isBlank((String) params.get("loginUserId"))) {
                    message.setMessage("操作人的ID不能为空");
                    message.setSuccess(false);
                    message.setCode("-1");
                    return message;
                } else {
                    loginUserId = Integer.valueOf((String) params.get("loginUserId"));
                }
            }
            if (null == loginUserId) {
                message.setMessage("操作人的ID不能为空");
                message.setSuccess(false);
                message.setCode("-1");
                return message;
            }

            if (params.get("operationName") == null){
                message.setMessage("操作人姓名不能为空！！！");
                message.setSuccess(false);
                message.setCode("-1");
                return message;
            }
            String payTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String remark = "操作人：" + loginUserId;
            String operationName = (String) params.get("operationName");
            PvOrder order = pvOrderMapper.selectById(orderId);
            Member member2 = memberMapper.selectOne(
                    Wrappers.lambdaQuery(Member.class)
                            .eq(Member::getPlatCustNo, platCompanyNo)
                            .eq(Member::getDeleted, 0)
            );
            if (null != order) {
                Member member = memberMapper.selectOne(
                        Wrappers.lambdaQuery(Member.class)
                                .eq(Member::getUserId, order.getDelistingUserId())
                                .eq(Member::getDeleted, 0)
                );

                ApplyWithdrawReqVo reqVo = new ApplyWithdrawReqVo();
                reqVo.setVerificationCode((String) params.get("verificationCode"));
                Map<String, List<OrderReqVo>> items = new HashMap<>();
                reqVo.setItems(items);
                List<OrderReqVo> reqVos = new ArrayList<>();
                items.put(member.getPlatCustNo(),reqVos);

                OrderReqVo orderReqVo = new OrderReqVo();
                orderReqVo.setOrderId(order.getId());
                orderReqVo.setTotalAmount(order.getTotalAmount().subtract(order.getPoundage()));
                reqVos.add(orderReqVo);

                String returnJson = XmPayJwtTokenUtil.xmPayPost(restTemplate, remitUrl, JSONObject.toJSONString(reqVo), member2.getIdNo());
                JSONObject jsonObject = JSONObject.parseObject(returnJson);

                List<Integer> success;
                List<Integer> error;

                if (jsonObject.getBoolean("success")){
                    JSONObject data = jsonObject.getJSONObject("data");
                    success = JSONArray.parseArray(data.getString("success"),Integer.class);
                    error =   JSONObject.parseArray(data.getString("error"), Integer.class);
                    PvOrder pvOrder = new PvOrder();
                    if (!CollectionUtils.isEmpty(success)){
                        for (Integer id : success) {
                            pvOrder.setPaymentState(104);
                            updateOrder(id,payTime,loginUserId,operationName,pvOrder,remark);
                        }
                    }
                    if (!CollectionUtils.isEmpty(error)){
                        for (Integer id : error) {
                            pvOrder.setPaymentState(105);
                            updateOrder(id,payTime,loginUserId,operationName,pvOrder,remark);
                        }
                    }
                }else {
                    message.setCode("-1");
                    message.setMessage((String) jsonObject.get("message"));
                    return message;
                }
                message.setSuccess(true);
                message.setMessage(ResponseData.DEFAULT_SUCCESS_MESSAGE);
                message.setCode("200");
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                message.setSuccess(false);
                message.setMessage("无数据");
                message.setCode("-1");
            }
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            message.setSuccess(false);
            message.setMessage("无数据");
            message.setCode("-1");
            e.printStackTrace();
        }
        return message;
    }

    private void updateOrder(Integer id, String payTime, Integer loginUserId, String operationName, PvOrder pvOrder, String remark) {
        pvOrder.setId(id);
        pvOrder.setPayTime(payTime);
        pvOrder.setUserId(loginUserId);
        pvOrder.setRemark(remark);
        pvOrder.setOperationName(operationName);
        // 防止回调比我们响应自己服务响应更快，回调改
        pvOrder.setOperationName(operationName);
        // 防止回调比我们响应自己服务响应更快，回调改了状态这儿又重新改回打款中,sql中加了状态不等于1
        int i = pvOrderMapper.collectCashUpdate(pvOrder);
        if (i < 1){
            pvOrderMapper.collectCashUpdateNotState(pvOrder);
        }
    }


    @Override
    @Transactional
    public BusinessMessage updateBatchRemitStatus(Map<String, Object> params) {
        BusinessMessage message = new BusinessMessage();
        try {
            String verificationCode = (String) params.get("verificationCode");
            if (StringUtils.isBlank(verificationCode)){
                message.setMessage("验证码不能为空！！！");
                message.setSuccess(false);
                message.setCode("-1");
                return message;
            }
            List<Integer> orderIds = (List<Integer>) params.get("orderIds");
            if (null == orderIds && orderIds.size() <= 0) {
                message.setMessage("ID不能为空");
                message.setSuccess(false);
                message.setCode("-1");
                return message;
            }
            BusinessMessage message1 = checkoutOrder(message, orderIds);
            if (message1 != null){
                return message1;
            }
            Integer loginUserId = GetJavaTypeConvert.getInteger(params.get("loginUserId"));
            String payTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String remark = "操作人：" + loginUserId;
            String operationName = (String) params.get("operationName");
            if (null == loginUserId) {
                message.setMessage("操作人的ID不能为空");
                message.setSuccess(false);
                message.setCode("-1");
                return message;
            }
            if (StringUtils.isEmpty(operationName)){
                message.setMessage("操作人姓名不能为空！！！");
                message.setSuccess(false);
                message.setCode("-1");
                return message;
            }

            List<PvOrder> pvOrders = pvOrderMapper.selectBatchIds(orderIds);

            Map<Integer, List<PvOrder>> collect = pvOrders.stream().collect(Collectors.groupingBy(PvOrder::getDelistingUserId));

            List<Member> members = memberMapper.selectList(
                    Wrappers.lambdaQuery(Member.class)
                            .in(Member::getUserId, collect.keySet())
                            .eq(Member::getDeleted, 0)
            );

            Member member2 = memberMapper.selectOne(
                    Wrappers.lambdaQuery(Member.class)
                            .eq(Member::getPlatCustNo, platCompanyNo)
                            .eq(Member::getDeleted, 0)
            );

            Map<Integer, Member> memberMap = members.stream().collect(Collectors.toMap(Member::getUserId, o -> o));
            ApplyWithdrawReqVo reqVo = new ApplyWithdrawReqVo();
            reqVo.setVerificationCode((String) params.get("verificationCode"));
            Map<String, List<OrderReqVo>> items = new HashMap<>();
            reqVo.setItems(items);

            for (PvOrder order : pvOrders) {
                String key = memberMap.get(order.getDelistingUserId()).getPlatCustNo();
                List<OrderReqVo> reqVos1 = items.get(key);
                if (reqVos1 == null){
                    reqVos1 = Lists.newArrayList();
                    items.put(memberMap.get(order.getDelistingUserId()).getPlatCustNo(),reqVos1);
                }
                OrderReqVo orderReqVo = new OrderReqVo();
                orderReqVo.setOrderId(order.getId());
                orderReqVo.setTotalAmount(order.getTotalAmount().subtract(order.getPoundage()));
                reqVos1.add(orderReqVo);
            }

            String returnJson = XmPayJwtTokenUtil.xmPayPost(restTemplate, remitUrl, JSONObject.toJSONString(reqVo), member2.getIdNo());
            JSONObject jsonObject = JSONObject.parseObject(returnJson);
            if (!jsonObject.getBoolean("success")){
                message.setCode("-1");
                message.setMessage((String) jsonObject.get("message"));
                return message;
            }

            JSONObject data = jsonObject.getJSONObject("data");

            List<Integer> success = JSONArray.parseArray(data.getString("success"),Integer.class);
            List<Integer> error =   JSONObject.parseArray(data.getString("error"), Integer.class);
            PvOrder pvOrder = new PvOrder();
            if (!CollectionUtils.isEmpty(success)){
                for (Integer id : success) {
                    pvOrder.setPaymentState(104);
                    updateOrder(id,payTime,loginUserId,operationName,pvOrder,remark);
                }
            }
            if (!CollectionUtils.isEmpty(error)){
                for (Integer id : error) {
                    pvOrder.setPaymentState(105);
                    updateOrder(id,payTime,loginUserId,operationName,pvOrder,remark);
                }
            }

            message.setSuccess(true);
            message.setMessage("处理成功！");
            message.setCode("200");
            return message;
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            message.setSuccess(false);
            message.setMessage("无数据");
            message.setCode("-1");
            e.printStackTrace();
        }
        return message;
    }

    @Override
    public BusinessMessage cwSendVerificationCode(List<Integer> orderIds){
        BusinessMessage message = new BusinessMessage();
        BusinessMessage message1 = checkoutOrder(message, orderIds);
        if (message1 != null){
            return message1;
        }
        Object cw_send_verification_code = redisUtils.get("CW_SEND_VERIFICATION_CODE");
        if (cw_send_verification_code != null){
            message.setCode("-1");
            message.setMessage("请勿频繁操作");
            return message;
        }
        Member member = memberMapper.selectOne(
                Wrappers.lambdaQuery(Member.class)
                        .eq(Member::getPlatCustNo, platCompanyNo)
                        .eq(Member::getDeleted, 0)
        );
        SendVerificationParam sendVerificationParam = new SendVerificationParam();
        sendVerificationParam.setBizType(BizType.MEMBERTRANSFER);

        String returnJson = XmPayJwtTokenUtil.xmPayPost(restTemplate, sendVerificationCode, JSONObject.toJSONString(sendVerificationParam), member.getIdNo());
        JSONObject jsonObject = JSONObject.parseObject(returnJson);
        if (jsonObject.getBoolean("success")){
            message.setSuccess(true);
            message.setCode("200");
            message.setMessage("成功");
        }else {
            message.setSuccess(false);
            message.setCode("-1");
            message.setMessage("获取验证码失败！");
        }
        redisUtils.set("CW_SEND_VERIFICATION_CODE","CW_SEND_VERIFICATION_CODE",60);
        return message;
    }

    private BusinessMessage  checkoutOrder(BusinessMessage message, List<Integer> orderIds){
        List<PvOrder> pvOrders = pvOrderMapper.selectBatchIds(orderIds);
        if (CollectionUtils.isEmpty(pvOrders)){
            message.setMessage("选择订单Id为空");
            message.setCode("-1");
            return message;
        }

        for (PvOrder pvOrder : pvOrders) {
            if (pvOrder.getPaymentState() == 1 || pvOrder.getPaymentState() == 104){
                message.setMessage("选择订单存在已打款订单，或打款中订单，请勿重复操作");
                message.setCode("-1");
                return message;
            }
        }
        return null;
    }

    @Override
    public BusinessMessage getMemberWithdraw(MemberWithdrawReqVo reqVo){
        BusinessMessage message = new BusinessMessage();
        GetMemberWithdrawRespVo respVo = new GetMemberWithdrawRespVo();

        BindCardApply bindCardApply = bindCardApplyMapper.selectOne(
                Wrappers.lambdaQuery(BindCardApply.class)
                        .eq(BindCardApply::getUserId,  reqVo.getUserId())
                        .eq(BindCardApply::getDeleted, 0)
                        .eq(BindCardApply::getStatus, 1)
                        .eq(BindCardApply::getSettleFlag,"Y"));
        respVo.setCardNo(bindCardApply.getCardNo());
        respVo.setOpenBankName(bindCardApply.getOpenBankName());

        BranchFundInquiryParam param = new BranchFundInquiryParam();
        param.setUserId(reqVo.getUserId());
        param.setAcctType(SubAccountType.WITHDRAW);
        BusinessMessage message1 = this.memberBranchFundInquiry(param);
        Map data = (Map)message1.getData();
        respVo.setAmount(new BigDecimal((String) data.get("bal")));
        message.setSuccess(true);
        message.setMessage("成功！");
        message.setData(respVo);
        message.setCode("200");
        return message;
    }

    @Override
    @Transactional
    public BusinessMessage memberWithdraw(MemberWithdrawReqVo reqVo){
        BusinessMessage message = new BusinessMessage();

        if (reqVo.getSysUserId() == null) {
            message.setMessage("操作人的ID不能为空");
            message.setSuccess(false);
            message.setCode("-1");
            return message;
        }

        if (StringUtils.isBlank(reqVo.getOperationName())){
            message.setMessage("操作人姓名不能为空！！！");
            message.setSuccess(false);
            message.setCode("-1");
            return message;
        }

        //生成订单明细
        PvOrder pvOrder = new PvOrder();
        String orderNum = OrderNumGeneration.generateOrderId();  //生成订单号
        pvOrder.setSerialNumber(orderNum);
        pvOrder.setRemark("用户申请余额到钱包:" + reqVo.getAmount().toString());
        pvOrder.setPurchaseMethod(4);
        pvOrder.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        pvOrder.setUpdatedAt(new Date());
        pvOrder.setDelistingUserId(reqVo.getUserId());
        pvOrder.setPaymentState(104);
        pvOrder.setPaymentChannel(3);
        pvOrder.setTotalAmount(reqVo.getAmount());
        pvOrder.setNotFzMoney(reqVo.getAmount());
        pvOrder.setFzMoney(BigDecimal.ZERO);
        pvOrder.setPoundage(BigDecimal.ZERO);
        pvOrder.setUserId(reqVo.getSysUserId());
        pvOrder.setPayTime(DateUtils.newDate(DateUtils.YYYY_MM_DD_HH_MM_SS));
        pvOrder.setOperationName(reqVo.getOperationName());
        pvOrderMapper.insert(pvOrder);
        Member member = memberMapper.selectOne(
                Wrappers.lambdaQuery(Member.class)
                        .eq(Member::getUserId, reqVo.getUserId())
                        .eq(Member::getDeleted, 0)
        );

        // 封装参数
        CwWithdrawalVo param = new CwWithdrawalVo();
        param.setIdNo(member.getIdNo());
        param.setTotalAmount(reqVo.getAmount());
        param.setOrderId(pvOrder.getId());

        Member member2 = memberMapper.selectOne(
                Wrappers.lambdaQuery(Member.class)
                        .eq(Member::getPlatCustNo, platCompanyNo)
                        .eq(Member::getDeleted, 0)
        );

        String returnJson = XmPayJwtTokenUtil.xmPayPost(restTemplate, memberWithdrawal, JSONObject.toJSONString(param), member2.getIdNo());
        JSONObject jsonObject = JSONObject.parseObject(returnJson);

        if ((boolean) jsonObject.get("success")){
            message.setCode("200");
            message.setSuccess(true);
            message.setData(jsonObject.get("data"));
            return message;
        }else {
            message.setCode("-1");
            message.setMessage((String) jsonObject.get("message"));
            return message;
        }

    }

    @Override
    public BusinessMessage see(Integer orderId){
        BusinessMessage message = new BusinessMessage();
        message.setSuccess(true);
        message.setCode("200");
        PvOrder pvOrder = pvOrderMapper.selectById(orderId);
        PlatformSeeVo platformSeeVo = new PlatformSeeVo();
        platformSeeVo.setOrderId(orderId);
        Member member2 = memberMapper.selectOne(
                Wrappers.lambdaQuery(Member.class)
                        .eq(Member::getPlatCustNo, platCompanyNo)
                        .eq(Member::getDeleted, 0)
        );
        String json = XmPayJwtTokenUtil.xmPayPost(restTemplate, platformSee, JSONObject.toJSONString(platformSeeVo),member2.getIdNo());
        JSONObject object = JSONObject.parseObject(json);
        Boolean success = object.getBoolean("success");
        BranchFundInquiryParam param = new BranchFundInquiryParam();
        param.setAcctType(SubAccountType.WITHDRAW);
        param.setUserId(pvOrder.getDelistingUserId());
        BusinessMessage message1 = memberBranchFundInquiry(param);
        if (!success){
            message.setData("打款失败原因：原因未知！");
        }
        MemberWithdrawal order_ids = object.getObject("data",MemberWithdrawal.class);
        Map data = (Map)message1.getData();
        String bal = null;
        if (data!=null){
            bal = (String)data.get("bal");
        }
        if (order_ids == null){
            message.setData("打款失败原因：原因未知！当前用户虚拟户余额为："+bal);
        }else {
            if (order_ids.getStatus() == 1){
                message.setData("打款成功：已经回调！");
            }else {
                try {
                    JSONObject jsonObject = JSONObject.parseObject(order_ids.getRemark());
                    message.setData("打款失败原因：厦门报错！"+jsonObject.getString("errInfo")+"    当前用户虚拟户余额为："+bal);
                }catch (Exception e){
                    message.setData("打款失败原因：原因未知！当前用户虚拟户余额为："+bal);
                }
            }
        }
        return message;
    }


    /**
     * 打款失败，重新打款
     * @param orderId
     * @return
     */
    @Override
    public BusinessMessage memberWithdrawAgainRemit(Integer orderId){
        BusinessMessage message = new BusinessMessage();
        PvOrder pvOrder = pvOrderMapper.selectById(orderId);
        if (pvOrder == null){
            message.setCode("-1");
            message.setMessage("订单不存在！");
            return message;
        }
        BranchFundInquiryParam param = new BranchFundInquiryParam();
        param.setAcctType(SubAccountType.WITHDRAW);
        param.setUserId(pvOrder.getDelistingUserId());
        BusinessMessage message1 = memberBranchFundInquiry(param);
        Map data = (Map)message1.getData();
        String bal = (String)data.get("bal");
        BigDecimal bigDecimal = new BigDecimal(bal);
        if (bigDecimal.compareTo( pvOrder.getTotalAmount().subtract(pvOrder.getPoundage())) < 0){
            message.setCode("-1");
            message.setMessage("余额不足提现失败！");
            return message;
        }

        Member member = memberMapper.selectOne(new QueryWrapper<Member>().eq("user_id", pvOrder.getDelistingUserId()).eq("is_xm_data", 1));
        if (member == null){
            message.setCode("-1");
            message.setMessage("该用户不是厦门认证用户！");
            return message;
        }

        CwWithdrawalVo MemberWithdrawalParam = new CwWithdrawalVo();
        MemberWithdrawalParam.setIdNo(member.getIdNo());
        MemberWithdrawalParam.setTotalAmount(pvOrder.getTotalAmount().subtract(pvOrder.getPoundage()));
        MemberWithdrawalParam.setOrderId(pvOrder.getId());


        Member member1 = memberMapper.selectOne(
                Wrappers.lambdaQuery(Member.class)
                        .eq(Member::getPlatCustNo, platCompanyNo)
                        .eq(Member::getDeleted, 0)
        );

        String returnJson = XmPayJwtTokenUtil.xmPayPost(restTemplate, memberWithdrawal, JSONObject.toJSONString(MemberWithdrawalParam), member1.getIdNo());
        JSONObject jsonObject = JSONObject.parseObject(returnJson);
        if ((boolean) jsonObject.get("success")){
            message.setCode("200");
            message.setSuccess(true);
            message.setData(jsonObject.get("data"));
            pvOrder.setPaymentState(104);
            pvOrderMapper.updateById(pvOrder);
            return message;
        }else {
            pvOrder.setPaymentState(105);
            pvOrderMapper.updateById(pvOrder);
            message.setCode("-1");
            message.setMessage((String) jsonObject.get("message"));
            return message;
        }
    }
}
